#include "MinerStates.hpp"

#include <iostream>

#include <SmegCore/Game/MessageDispatcher.hpp>

#include "MessageTypes.h"

//--------------------------------------------------------
void EnterMineAndDigForNugget::OnEnter( Miner* _pEntity ) {
    std::cout << "--------- Miner entering the mine!" << std::endl;
}

void EnterMineAndDigForNugget::OnUpdate( Miner* _pEntity ) {
    _pEntity->IncreaseThirst();
    _pEntity->IncreaseFatigue();
    _pEntity->AddGoldCarried( 1 );

    std::cout << "------ Miner digging some gold, now have " << _pEntity->GetGoldCarried() << " in my pockets!" << std::endl;

    if ( _pEntity->ArePocketFull() ) {
        _pEntity->GetStateMachine()->ChangeState( VisitBankAndDepositGold::GetInstance() );
    } else if ( _pEntity->IsThirsty() ) {
        _pEntity->GetStateMachine()->ChangeState( QuenchThirst::GetInstance() );
    }
}

void EnterMineAndDigForNugget::OnExit( Miner* _pEntity ) {
    std::cout << "--------- Miner leaving the mine!" << std::endl;
}

//--------------------------------------------------------
void VisitBankAndDepositGold::OnEnter( Miner* _pEntity ) {
    std::cout << "--------- Miner entering the bank!" << std::endl;
}

void VisitBankAndDepositGold::OnUpdate( Miner* _pEntity ) {
    _pEntity->AddGoldToWealth( _pEntity->GetGoldCarried() );
    _pEntity->SetGoldCarried( 0 );
    
    std::cout << "------ Miner now have " << _pEntity->GetWealth() << " gold in the bank!" << std::endl;

    if ( _pEntity->IsWealthy() ) {
        _pEntity->GetStateMachine()->ChangeState( GoHomeAndSleepTilRested::GetInstance() );
    } else {
        _pEntity->GetStateMachine()->RevertToPreviousState();
    }
}

void VisitBankAndDepositGold::OnExit( Miner* _pEntity ) {
    std::cout << "--------- Miner leaving the bank!" << std::endl;
}

//--------------------------------------------------------
void QuenchThirst::OnEnter( Miner* _pEntity ) {
    std::cout << "--------- Miner entering the saloon!" << std::endl;
}

void QuenchThirst::OnUpdate( Miner* _pEntity ) {
    std::cout << "------ Miner drinking some whiskey!" << std::endl;

    _pEntity->BuyAndDrinkAWhiskey();

    _pEntity->GetStateMachine()->RevertToPreviousState();
}

void QuenchThirst::OnExit( Miner* _pEntity ) {
    std::cout << "--------- Miner leaving the saloon!" << std::endl;
}

//--------------------------------------------------------
void GoHomeAndSleepTilRested::OnEnter( Miner* _pEntity ) {
    std::cout << "--------- Miner got back home!" << std::endl;

    if ( !_pEntity->GetStateMachine()->IsLastState( EatStew::GetInstance() ) ) {
        smeg::core::MessageDispatcher::GetInstance()->DispatchMessage(
            MSG_SEND_IMMEDIATELY,
            _pEntity,
            _pEntity->GetWife(),
            eMsg_HoneyImHome,
            NO_EXTRA_INFO );
    }
}

void GoHomeAndSleepTilRested::OnUpdate( Miner* _pEntity ) {
    std::cout << "------ ZzzzZzzzZzzz..." << std::endl;

    _pEntity->DecreaseFatigue();

    if ( !_pEntity->IsTired() ) {
        _pEntity->GetStateMachine()->ChangeState( EnterMineAndDigForNugget::GetInstance() );
    }
}

void GoHomeAndSleepTilRested::OnExit( Miner* _pEntity ) {
}

bool GoHomeAndSleepTilRested::HandleMessage( Miner* _pEntity, const smeg::core::MessageInfo& _msg ) {
    if ( _msg.m_iMessageType == eMsg_StewReady ) {
        _pEntity->GetStateMachine()->ChangeState( EatStew::GetInstance() );

        return true;
    }

    return false;
}

//--------------------------------------------------------
void EatStew::OnEnter( Miner* _pEntity ) {
    std::cout << "--------- Miner eating the stew!" << std::endl;
}

void EatStew::OnUpdate( Miner* _pEntity ) {
    std::cout << "------ Miner love the stew!" << std::endl;

    _pEntity->GetStateMachine()->RevertToPreviousState();
}

void EatStew::OnExit( Miner* _pEntity ) {
    std::cout << "--------- Miner go back to sleep!" << std::endl;
}